﻿/*
 * zstring.cxx
 *
 *  Created on: 2015年4月3日
 *      Author: Fifi Lyu
 */

#include "zpsoe/zalgorithm/zstring.h"
#include "zpsoe/zexception.h"

namespace zpsoe {

namespace zalgorithm {

namespace zstring {

ZPSOE_SHARED_LIB_API bool find(const string &str, const string &sub_str) {
    if (sub_str.size() > str.size() || str.find(sub_str) == string::npos) {
        return false;
    }

    return true;
}

ZPSOE_SHARED_LIB_API string trim(const string &s, const string &white_space) {
    const size_t start_ = s.find_first_not_of(white_space);

    // 字符串只由空白字符组成
    if (start_ == string::npos) return "";

    const size_t end_ = s.find_last_not_of(white_space);

    return s.substr(start_, end_ - start_ + 1);
}

ZPSOE_SHARED_LIB_API string replace(
        const string& str, const string& old_substr, const string& new_substr) {
    if (str.empty())
        return "";

    if (old_substr.empty()
                || new_substr.empty()
                    || old_substr == new_substr)
        return str;

    size_t pos = 0;
    string str_(str);

    // find(old_substr,pos)防止出现man替换为woman之类的情况，出现死循环
    while ((pos = str_.find(old_substr, pos)) != string::npos) {
        str_.replace(pos, old_substr.size(), new_substr);
        pos += new_substr.size();
    }

    return str_;
}

ZPSOE_SHARED_LIB_API string erase(const string &str, const string &sub_str) {
    string str_tmp_(str);

    if (str.size() && sub_str.size() && find(str, sub_str)) {
        size_t pos_(0);
        size_t erase_pos_(0);
        size_t sub_str_size = sub_str.size();

        // 注意：此代码将防止出现mnmmnn中2次删除mn，剩下第三位的m和最后的n时， 多执行了一次删除
        while ((pos_ = str.find(sub_str, pos_)) != string::npos) {
            // 在新字符串长度比输入的字符串长度短erase_pos_
            // 所以，在新字符串中起点向后移动erase_pos_
            str_tmp_.erase((pos_ - erase_pos_), sub_str_size);
            erase_pos_ += sub_str_size;
            pos_ += sub_str.size();
        }
    }

    return str_tmp_;
}

ZPSOE_SHARED_LIB_API bool is_version(const string &str) {
    if (str.empty()) {
        return false;
    }

    //  开头和结尾不能是点
    if ((str[0] == '.') || (str[str.size() - 1] == '.')) {
        return false;
    }

    for (size_t i = 0; i < str.size(); i++) {
        char char_block = str[i];
        if (isdigit(char_block) || char_block == '.') {
            continue;
        } else {
            return false;
        }
    }

    return true;
}

ZPSOE_SHARED_LIB_API bool is_digit(const string &str) {
    if (str.empty())
        return false;

    for (size_t i = 0; i < str.size(); i++) {
        if (!isdigit(str[i]))
            return false;
    }

    return true;
}

ZPSOE_SHARED_LIB_API bool is_alnum(const string &str) {
    if (str.empty())
        return false;

    for (size_t i = 0; i < str.size(); i++) {
        if (!isalnum(str[i]))
            return false;
    }

    return true;
}

ZPSOE_SHARED_LIB_API bool is_alpha(const string &str) {
    if (str.empty())
        return false;

    for (size_t i = 0; i < str.size(); i++) {
        if (!isalpha(str[i]))
            return false;
    }

    return true;
}

ZPSOE_SHARED_LIB_API string to_lower(const string &s) {
    string s_("");

    for (string::const_iterator it_ = s.begin(); it_ != s.end();++it_)
        s_ += tolower(*it_);

    return s_;
}

ZPSOE_SHARED_LIB_API string to_upper(const string &s) {
    string s_("");

    for (string::const_iterator it_ = s.begin(); it_ != s.end();++it_)
        s_ += toupper(*it_);

    return s_;
}

ZPSOE_SHARED_LIB_API void to_vector(
        const string &s, vector<string> &v, const string &sep) {
    v.clear();

    size_t sep_pos_ = 0;
    size_t start_pos_ = 0;
    size_t sub_size_ = 0;
    const size_t size_ = v.size();
    const size_t last_sep_pos_ = s.find_last_of(sep);

    while (true) {
        sep_pos_ = s.find_first_of(sep, start_pos_);

        // 没有找到指定的分隔符，列表元素数量为 1
        if (sep_pos_ == string::npos) {
            v.push_back(s);
            break;
        }

        sub_size_ = sep_pos_ - start_pos_;
        v.push_back(s.substr(start_pos_, sub_size_));

        start_pos_ = sep_pos_ + 1;

        // 字符串最后一个字符刚好是分隔符。
        // 比如 a+b+c+ 中最后一个加号刚好是分隔符
        if (sep_pos_ == size_) {
            v.push_back("");
            break;
        }

        // 最后一个分隔符
        // 比如 a+b+c 中第二个加号
        if (sep_pos_ == last_sep_pos_) {
            v.push_back(s.substr(start_pos_));
            break;
        }
    }
}

ZPSOE_SHARED_LIB_API void to_map(
        const vector<string> &v, map<string, string> &m) {
    for (vector<string>::const_iterator it_ = v.begin();
            it_ != v.end(); ++it_)
        m[(*it_)] = "";
}

ZPSOE_SHARED_LIB_API void to_map(
        const string &s, map<string, string> &m, const string &sep) {
    vector<string> v_;

    to_vector(s, v_, sep);
    to_map(v_, m);
}

} /* namespace zstring */

} /* namespace zalgorithm */

} /* namespace zpsoe */
